import { exrpd } from "../util/exrpd";
import { BlockchainConfigType } from "../config.type";

type NodeInfo = {
    moniker: string;
    id: string;
    address: string;
    publicKey: string;
};

const Defaults = {
    keyring: "test",
    keyName: "key",
    keyAlgorithm: "eth_secp256k1",
};

export class NodeService {
    constructor(private config: BlockchainConfigType, private moniker: string, private path: string) {}

    get dockerImage(): string {
        return "peersyst/xrp-evm-blockchain:latest";
    }

    get chainId(): string {
        return `exrp_${this.config.chainId}-1`;
    }

    configKeyring() {
        exrpd(`config keyring-backend ${Defaults.keyring}`, this.path, this.dockerImage);
    }

    configChainId() {
        exrpd(`config chain-id ${this.chainId}`, this.path, this.dockerImage);
    }

    addKeys() {
        exrpd(
            `keys add ${Defaults.keyName} --keyring-backend ${Defaults.keyring} --algo ${Defaults.keyAlgorithm}`,
            this.path,
            this.dockerImage,
        );
    }

    init() {
        exrpd(`init ${this.moniker} --chain-id ${this.chainId}`, this.path, this.dockerImage);
    }

    parseHexAddressToBech32(address: string): string {
        const { formats } = JSON.parse(exrpd(`keys parse ${address.replace("0x", "")} --output json`, this.path, this.dockerImage));
        return formats[0];
    }

    get info(): NodeInfo {
        const nodeId = exrpd(
            `tendermint show-node-id --chain-id ${this.chainId} --keyring-backend ${Defaults.keyring}`,
            this.path,
            this.dockerImage,
        ).replace(/\n$/, "");

        return {
            moniker: this.moniker,
            id: nodeId,
            address: JSON.parse(exrpd(`keys list --keyring-backend ${Defaults.keyring} --output json`, this.path, this.dockerImage))[0]
                .address,
            publicKey: exrpd(`tendermint show-validator`, this.path, this.dockerImage).replace(/\n$/, ""),
        };
    }

    addGenesisAccount(address: string, amount: string) {
        exrpd(`add-genesis-account ${address} ${amount} --keyring-backend ${Defaults.keyring}`, this.path, this.dockerImage);
    }

    signGenesisStakeTransaction(amount: string) {
        const nodeInfo = this.info;
        return exrpd(
            `--node-id ${nodeInfo.id} --pubkey "${nodeInfo.publicKey.replace(/"/g, '\\"')}" gentx ${
                Defaults.keyName
            } ${amount} --keyring-backend ${Defaults.keyring} --chain-id ${this.chainId}`,
            this.path,
            this.dockerImage,
        );
    }

    collectGenTxs() {
        exrpd("collect-gentxs", this.path, this.dockerImage);
    }

    initNode() {
        this.configKeyring();
        this.configChainId();
        this.addKeys();
        this.init();
    }
}
